/**
 * @file        Map.ts
 * @author      shenyc
 * @date        2021-08-10
 * @copyright   Copy right (c) shenyc (shenyczz@163.com).
 *              All rights reserved.
 *
******************************************************************************/
// {{@@@}}
'use strict';
// ----------------------------------------------------------------------------
import * as Cesium from "cesium"
// ----------------------------------------------------------------------------
import { Target } from "./Target"
import { ChinaBox } from "../common"
// ChinaBox
// ----------------------------------------------------------------------------
/**
 * Map
 * @author shenyc
 * @description 地图类
 * @param {} [options] see {@link Map.ConstructorOptions}
 */
export class Map extends Target {
    //
    constructor(container: HTMLElementLike, options?: Map.ConstructorOptions) {
        super(options);

        this.setup_cesium();
        this.setOptions(options);
        this.init(container);
    }

    // [1 静态实例]
    // ------------------------------------------------------------------------ 静态实例
    private static _instance: Map;
    /** 确保全局只有一个实例, 在 init 中赋值 */
    public static get Instance() { return Map._instance; }
    // Map.init 完成后必须绑定实例
    private static bindInstance = (instance: Map) => Map._instance = instance;

    // public static Map1234: { name: string; map: Map }[] = [];
    // ------------------------------------------------------------------------

    // [2 Cesium Object]
    // #region ------------------------------------------------------------------------ Cesium Object begin
    // Cesium Object
    private _viewer!: Cesium.Viewer;
    public getViewer = () => this._viewer as Cesium.Viewer;

    // viewer
    public get dataSources() { return this.getViewer().dataSources as Cesium.DataSourceCollection }
    public get entities() { return this.getViewer().entities as Cesium.EntityCollection }
    public get imageryLayers() { return this.getViewer().imageryLayers as Cesium.ImageryLayerCollection }
    // viewer.scene
    public get primitives() { return this.getViewer().scene.primitives as Cesium.PrimitiveCollection }
    // viewer.clock
    public get shouldAnimate() { return this.getViewer().clock.shouldAnimate; }
    public set shouldAnimate(value: boolean) { this.getViewer().clock.shouldAnimate = value; }

    // private _layers: Layer[] = [];
    // public getLayers = () => this._layers;
    // ------------------------------------------------------------------------ custom members end

    // [4 init]
    // ------------------------------------------------------------------------ init begin
    /**
     * 初始化
     * @param container 容器
     * @param options 选项
     */
    private init(container: HTMLElementLike) {
        // --------------------------------------------------------------------
        // 处理 Cesium Viewer ConstructorOptions
        const mapOptions = this.getOptions() as Map.ConstructorOptions;
        const { options } = mapOptions;
        const viewerOptions = Object.assign({}, Map.defaultViewerOptions, options);
        // viewerOptions.homeButton = true;
        // --------------------------------------------------------------------
        //  构造 Cesium.Viewer
        this._viewer = new Cesium.Viewer(container, viewerOptions as Cesium.Viewer.ConstructorOptions);
        // --------------------------------------------------------------------
        const viewer = this.getViewer();
        viewer.imageryLayers.removeAll();
        viewer.creditDisplay.container.style.cssText = "display: none"; // 隐藏信用标识
        // --------------------------------------------------------------------
        // 场景设置 scene
        // viewer.scene.sun.show = false;
        // viewer.scene.moon.show = false;
        // viewer.scene.undergroundMode = true;     // 开启地下模式
        // viewer.scene.globe.show = false;
        // viewer.scene.globe.baseColor = Cesium.Color.BLACK;   //
        // viewer.scene.backgroundColor = Cesium.Color.SKYBLUE; //
        // viewer.scene.skyBox.show = false;           // 关闭天空盒，否则会显示天空颜色
        // viewer.scene.skyAtmosphere.show = false;    // 大气层
        // viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100000;
        // viewer.scene.screenSpaceCameraController.maximumZoomDistance = 5600000;
        // viewer.scene.fxaa = true;
        // viewer.scene.postProcessStages.fxaa.enabled = true;
        // viewer.scene.globe._surface.tileProvider._debug.wireframe = enabled // 三角网 ?

        // 使用自定义背景
        // viewer.scene.sun.show = false;              // 隐藏太阳
        // viewer.scene.moon.show = false;             // 隐藏月亮
        // viewer.scene.skyBox.show = false;           // 隐藏天空盒
        // viewer.scene.skyAtmosphere.show = false;    // 隐藏大气圈
        // viewer.scene.backgroundColor = new Cesium.Color(0.0, 0.0, 0.0, 0.8);
        // --------------------------------------------------------------------
        // 5.2 添加 imageryLayer
        if (!viewerOptions.baseLayer) {
            // viewer.imageryLayers.removeAll();
            // viewer.imageryLayers.addImageryProvider(marios.ImageryProviders.imagery_cesium_earth_at_night); // 夜晚影像 ok
            // Cesium.IonImageryProvider.fromAssetId(marios.CesiumIonAssets.imagery.Earth_at_Night, {}).then(v => {
            //     viewer.imageryLayers.addImageryProvider(v);
            // });
        }
        // --------------------------------------------------------------------
        // 5.3 地形
        // viewer.terrainProvider = Cesium.createWorldTerrain(); // ok
        // marios.TerrainProviders.terrain_cesium_world.then(val => viewer.terrainProvider = val); // ok
        // --------------------------------------------------------------------
        // if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
        //     // 判断是否支持图像渲染像素化处理
        //     this.viewer.resolutionScale = window.devicePixelRatio;
        // }
        // --------------------------------------------------------------------
        // this.test();
        // --------------------------------------------------------------------
        Map.bindInstance(this);
        // --------------------------------------------------------------------
        console.debug("\t map init finished!");
        // --------------------------------------------------------------------
    }
    // ------------------------------------------------------------------------ init end



    // [5 public function]
    // #region ------------------------------------------------------------------------ public function begin

    /**
     * 添加图层 (设计事件监听处理...)
     * @param layer
     * @returns
     */
    // public addLayer(layer: Layer) {
    //     layer.bindMap(this);
    //     this._layers.push(layer);
    //     // onLayer_add_remove_change_edit Event
    //     return layer;
    // }

    /**
     *
     * @param duration
     */
    public flyHome(duration: number = 3.0) {
        this.getViewer().camera.flyHome(duration);
    }

    /**
     * 显示工具栏
     * @param show
     */
    // public showToolbar(show: boolean = true) {
    //     const tb = document.getElementById(ElementID.TOOLBAR) as HTMLElement;
    //     tb.style.display = show ? "inline" : "none";
    // }

    // #endregion ------------------------------------------------------------------------ public function end

    /**
     * 在构造实例时为 Cesium 开发环境设置全局配置
     */
    private setup_cesium() {
        //
        // const CESIUM_BASE_URL = "cesium";
        // const CESIUM_ACCESS_TOKEN =
        //     "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxOTE3NzA4Ny04MThiLTQwMzgtODE4Ni1mZWU5N2ZiYTBhZWMiLCJpZCI6MTU5MTYsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1NjkxNTI3MTl9.go1ZA9NegvqwBjzaHLh_4vovgsM7ZJudVDA3HEnMVPw";

        // 1 The URL on your server where CesiumJS's static files are hosted.
        // window.CESIUM_BASE_URL = CESIUM_BASE_URL;

        // 2 This is the default access token from your ion account
        // Cesium.Ion.defaultAccessToken = CESIUM_ACCESS_TOKEN

        // 3 Setup Home Rectangle
        const china_box = [ChinaBox.west, ChinaBox.south, ChinaBox.east, ChinaBox.north];
        Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(...china_box);

    }

    public static Setup(cesium_base_url: string, cesium_access_token: string) {
        //
        // 1 The URL on your server where CesiumJS's static files are hosted.
        window.CESIUM_BASE_URL = cesium_base_url;

        // 2 Setup Home Rectangle
        Cesium.Ion.defaultAccessToken = cesium_access_token
    }

    public static Create(container: HTMLElementLike, options?: Map.ConstructorOptions) {
        return new Map(container, options);
    }

    // {{END}}
}

export namespace Map {

    /**
     * @property [name]
     * @property [options] see {@link ViewerOptions}
     */
    export type ConstructorOptions = {
        name?: string;
        options?: ViewerOptions;
    }

    /**
     * Initialization options for the Cesium Viewer constructor
     * <br/>
     * @property [animation = true] - If set to false, the Animation widget will not be created.
     * @property [automaticallyTrackDataSourceClocks = true] - If true, this widget will automatically track the clock settings of newly added DataSources, updating if the DataSource's clock changes.  Set this to false if you want to configure the clock independently.
     * @property [baseLayer = ImageryLayer.fromWorldImagery()] - The bottommost imagery layer applied to the globe. If set to <code>false</code>, no imagery provider will be added. This value is only valid if `baseLayerPicker` is set to false.
     * @property [baseLayerPicker = true] - If set to false, the BaseLayerPicker widget will not be created.
     * @property [blurActiveElementOnCanvasFocus = true] - If true, the active element will blur when the viewer's canvas is clicked. Setting this to false is useful for cases when the canvas is clicked only for retrieving position or an entity data without actually meaning to set the canvas to be the active element.
     * @property [clockViewModel = new ClockViewModel(clock)] - The clock view model to use to control current time.
     * @property [contextOptions] - Context and WebGL creation properties passed to {@link Cesium.Scene}.
     * @property [creditContainer] - The DOM element or ID that will contain the {@link Cesium.CreditDisplay}.  If not specified, the credits are added to the bottom of the widget itself.
     * @property [creditViewport] - The DOM element or ID that will contain the credit pop up created by the {@link Cesium.CreditDisplay}.  If not specified, it will appear over the widget itself.
     * @property [dataSources = new DataSourceCollection()] - The collection of data sources visualized by the widget. If this parameter is provided, the instance is assumed to be owned by the caller and will not be destroyed when the viewer is destroyed.
     * @property [depthPlaneEllipsoidOffset = 0.0] - Adjust the DepthPlane to address rendering artefacts below ellipsoid zero elevation.
     * @property [ellipsoid = Ellipsoid.default] - The default ellipsoid. {@link Cesium.Ellipsoid.default}
     * @property [fullscreenButton = true] - If set to false, the FullscreenButton widget will not be created.
     * @property [fullscreenElement = document.body] - The element or id to be placed into fullscreen mode when the full screen button is pressed.
     * @property [geocoder = true] - If set to false, the Geocoder widget will not be created.
     * @property [globe = new Globe(options.ellipsoid)] - The globe to use in the scene.  If set to <code>false</code>, no globe will be added and the sky atmosphere will be hidden by default.
     * @property [homeButton = true] - If set to false, the HomeButton widget will not be created.
     * @property [imageryProviderViewModels = createDefaultImageryProviderViewModels()] - The array of ProviderViewModels to be selectable from the BaseLayerPicker.  This value is only valid if `baseLayerPicker` is set to true.
     * @property [infoBox = true] - If set to false, the InfoBox widget will not be created.
     * @property [mapMode2D = MapMode2D.INFINITE_SCROLL] - Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction.
     * @property [mapProjection = new GeographicProjection(options.ellipsoid)] - The map projection to use in 2D and Columbus View modes.
     * @property [msaaSamples = 4] - If provided, this value controls the rate of multisample antialiasing. Typical multisampling rates are 2, 4, and sometimes 8 samples per pixel. Higher sampling rates of MSAA may impact performance in exchange for improved visual quality. This value only applies to WebGL2 contexts that support multisample render targets. Set to 1 to disable MSAA.
     * @property [maximumRenderTimeChange = 0.0] - If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
     * @property [navigationHelpButton = true] - If set to false, the navigation help button will not be created.
     * @property [navigationInstructionsInitiallyVisible = true] - True if the navigation instructions should initially be visible, or false if the should not be shown until the user explicitly clicks the button.
     * @property [orderIndependentTranslucency = true] - If true and the configuration supports it, use order independent translucency.
     * @property [projectionPicker = false] - If set to true, the ProjectionPicker widget will be created.
     * @property [requestRenderMode = false] - If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling reduces the CPU/GPU usage of your application and uses less battery on mobile, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
     * @property [scene3DOnly = false] - When <code>true</code>, each geometry instance will only be rendered in 3D to save GPU memory.
     * @property [sceneMode = SceneMode.SCENE3D] - The initial scene mode.
     * @property [sceneModePicker = true] - If set to false, the SceneModePicker widget will not be created.
     * @property [selectedImageryProviderViewModel] - The view model for the current base imagery layer, if not supplied the first available base layer is used.  This value is only valid if `baseLayerPicker` is set to true.
     * @property [selectedTerrainProviderViewModel] - The view model for the current base terrain layer, if not supplied the first available base layer is used.  This value is only valid if `baseLayerPicker` is set to true.
     * @property [shadows = false] - Determines if shadows are cast by light sources.
     * @property [shouldAnimate = false] - <code>true</code> if the clock should attempt to advance simulation time by default, <code>false</code> otherwise.  This option takes precedence over setting {@link Viewer#clockViewModel}.
     * @property [showRenderLoopErrors = true] - If true, this widget will automatically display an HTML panel to the user containing the error, if a render loop error occurs.
     * @property [selectionIndicator = true] - If set to false, the SelectionIndicator widget will not be created.
     * @property [skyBox] - The skybox used to render the stars. When <code>undefined</code> and the WGS84 ellipsoid used, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added.
     * @property [skyAtmosphere] - Blue sky, and the glow around the Earth's limb. Enabled when the WGS84 ellipsoid used. Set to <code>false</code> to turn it off.
     * @property [targetFrameRate] - The target frame rate when using the default render loop.
     * @property [terrain] - A terrain object which handles asynchronous terrain provider. Can only specify if options.terrainProvider is undefined.
     * @property [terrainProvider = new EllipsoidTerrainProvider()] - The terrain provider to use
     * @property [terrainProviderViewModels = createDefaultTerrainProviderViewModels()] - The array of ProviderViewModels to be selectable from the BaseLayerPicker.  This value is only valid if `baseLayerPicker` is set to true.
     * @property [terrainShadows = ShadowMode.RECEIVE_ONLY] - Determines if the terrain casts or receives shadows from light sources.
     * @property [timeline = true] - If set to false, the Timeline widget will not be created.
     * @property [useBrowserRecommendedResolution = true] - If true, render at the browser's recommended resolution and ignore <code>window.devicePixelRatio</code>.
     * @property [useDefaultRenderLoop = true] - True if this widget should control the render loop, false otherwise.
     * @property [vrButton = false] - If set to true, the VRButton widget will be created.
     */
    export type ViewerOptions = {
        /**
         * 显示动画控件
         * <p>If set to false, the Animation widget will not be created.</p>
         * @defaultValue true
         */
        animation?: boolean;
        /**
         * 自动追踪数据源时钟
         * <p>
         * 如果为true，则此小部件将自动跟踪新添加的数据源的时钟设置，并在数据源的时钟发生更改时进行更新。
         * 如果要独立配置时钟，请将此值设置为false。
         * </p>
         * @defaultValue true
         */
        automaticallyTrackDataSourceClocks?: boolean;
        /**
         * 基础图层
         * <p>
         * The bottommost imagery layer applied to the globe.
         * If set to <code>false</code>, no imagery provider will be added.
         * This value is only valid if `baseLayerPicker` is set to <code>false</code>.
         * </p>
         * @defaultValue ImageryLayer.fromWorldImagery()
         */
        baseLayer?: Cesium.ImageryLayer | false;
        /**
         * 基础图层选择器
         * <p>
         * If set to false, the BaseLayerPicker widget will not be created.
         * </p>
         * @defaultValue true
         */
        baseLayerPicker?: boolean;
        /**
         * 模糊画布焦点上的活动元素
         * <p>
         * If true, the active element will blur when the viewer's canvas is clicked.
         * Setting this to <code>false</code> is useful for cases when the canvas is clicked only for
         * retrieving position or an entity data without actually meaning to set the canvas to be the active element.
         * </p>
         * <p>
         * 如果为true，则当单击查看器的画布时，活动元素将会模糊。
         * 将此设置为false对于仅单击画布检索位置或实体数据而无意将画布设置为活动元素，将其设置为false非常有用。
         * </p>
         * @defaultValue true
         */
        blurActiveElementOnCanvasFocus?: boolean;
        /**
         * 控制当前时间的时钟视图模型
         * <p>
         * The clock view model to use to control current time.
         * </p>
         * @defaultValue new ClockViewModel(clock)
         */
        clockViewModel?: Cesium.ClockViewModel;
        /**
         * 传递到场景的上下文和WebGL创建属性
         * <p>
         * [contextOptions] - Context and WebGL creation properties passed to {@link Cesium.Scene}.
         * </p>
         * @defaultValue any ?
         */
        contextOptions?: Cesium.ContextOptions;
        /**
         * 信用标识容器
         * <p>
         * The DOM element or ID that will contain the {@link Cesium.CreditDisplay}.
         * If not specified, the credits are added to the bottom of the widget itself.
         * </p>
         * @defaultValue
         */
        creditContainer?: Element | string;
        /**
         * 信用标记视口
         * <p>
         * 包含由 Cesium 所创建的信用弹出窗口的DOM元素或ID。如果没有指定，它将出现在小部件本身上。
         * </p>
         * @defaultValue
         */
        creditViewport?: Element | string;
        /**
         * 数据源
         * <p>
         * 由该小部件可视化的数据源的集合。如果提供了此参数，则假设该实例为调用者所有，并且在查看器被销毁时不会被销毁。
         * </p>
         * @defaultValue new DataSourceCollection()
         */
        dataSources?: Cesium.DataSourceCollection;
        /**
         * 调整深度平面以解决椭球体零标高以下的渲染对象问题。
         * <p></p>
         * @defaultValue 0.0
         */
        depthPlaneEllipsoidOffset?: number;
        /**
         * 默认椭球体
         * <p></p>
         * @defaultValue Ellipsoid.default
         */
        ellipsoid?: Cesium.Ellipsoid;
        /**
         * 全屏按钮
         * <p></p>
         * @defaultValue true
         */
        fullscreenButton?: boolean;
        /**
         * 全屏模式的元素或 ID
         * <p></p>
         * @defaultValue document.body
         */
        fullscreenElement?: Element | string;
        /**
         * 地理编码器
         * <p></p>
         * @defaultValue true
         */
        geocoder?: boolean | Cesium.GeocoderService[];
        /**
         * 地球仪
         * <p>在场景中使用。如果设置为 false，则不会添加地球仪，默认情况下会隐藏天空大气层</p>
         * @defaultValue new Globe(options.ellipsoid)
         */
        globe?: Cesium.Globe | false;
        /**
         * 主页按钮
         * <p></p>
         * @defaultValue true
         */
        homeButton?: boolean;
        /**
         * 影像提供程序视图模型
         * <p>
         * 可从基本选择器中选择的供应商模型数组。这个值只有在 `baseLayerPicker` 被设置为true时才有效。
         * </p>
         * @defaultValue createDefaultImageryProviderViewModels()
         */
        imageryProviderViewModels?: Cesium.ProviderViewModel[];
        /**
         * 信息框
         * <p>
         * If set to false, the InfoBox widget will not be created.
         * </p>
         * @defaultValue
         */
        infoBox?: boolean;
        /**
         * 确定二维贴图是可旋转的还是可以在水平方向上无限滚动
         * <p></p>
         * @defaultValue
         */
        mapMode2D?: Cesium.MapMode2D;
        /**
         * 在二维和哥伦布视图模式中使用的地图投影
         * <p></p>
         * @defaultValue
         */
        mapProjection?: Cesium.MapProjection;
        /**
         * MSAA
         * <p>
         * 如果提供，这个值将控制多样本抗锯齿的速率, 典型的多采样率为每像素2、4，有时是8个样本。
         * 较高的MSAA采样率可能会影响性能，以换取提高的视觉质量。此值仅适用于支持多例渲染目标的WebGL2上下文。
         * 设置为1以禁用MSAA。
         * </p>
         * @defaultValue
         */
        msaaSamples?: number;
        /**
         * 请求渲染前允许的模拟时间的最大更改时间
         * <p>
         * 如果请求渲染模式为真，则此值定义请求渲染前允许的模拟时间的最大更改时间。{@see requestRenderMode}
         * </p>
         * @defaultValue
         */
        maximumRenderTimeChange?: number;
        /**
         * 导航帮助按钮
         * <p></p>
         * @defaultValue
         */
        navigationHelpButton?: boolean;
        /**
         * 导航指令最初可见
         * <p>
         * 如果导航指令最初应该是可见的，则为真，如果在用户明确单击按钮之前不应该显示，则为假。
         * </p>
         * @defaultValue
         */
        navigationInstructionsInitiallyVisible?: boolean;
        /**
         * 顺序独立半透明性
         * <p>如果为true且配置支持，则使用订单独立的半透明</p>
         * @defaultValue
         */
        orderIndependentTranslucency?: boolean;
        /**
         * 投影选择器
         * <p></p>
         * @defaultValue
         */
        projectionPicker?: boolean;
        /**
         * 请求渲染模式
         * <p>
         * 如果为true，则只在场景中的更改渲染帧。
         * 启用减少了您的应用程序的CPU/GPU使用，并在移动设备上使用更少的电池，但需要在此模式下显式地渲染一个新的帧。
         * 在对API的其他部分的场景进行更改后，在许多情况下这是必要的。
         * </p>
         * @defaultValue
         */
        requestRenderMode?: boolean;
        /**
         * 每个几何图形实例将只呈现在3D中，以保存GPU内存
         * <p></p>
         * @defaultValue
         */
        scene3DOnly?: boolean;
        /**
         * 初始场景模式
         * <p></p>
         * @defaultValue
         */
        sceneMode?: Cesium.SceneMode;
        /**
         * 场景模式选择器
         * <p></p>
         * @defaultValue
         */
        sceneModePicker?: boolean;
        /**
         * 选定的图像提供程序视图模型
         * <p>
         * 如果没有提供当前基础图像层的视图模型，则使用第一个可用的基础图像层。这个值只有在 `baseLayerPicker` 被设置为true时才有效。
         * </p>
         * @defaultValue
         */
        selectedImageryProviderViewModel?: Cesium.ProviderViewModel;
        /**
         * 选定的地形提供程序视图模型
         * <p>
         * 如果没有提供当前基础地形层的视图模型，则使用第一个可用的基础地形层。这个值只有在 `baseLayerPicker` 被设置为true时才有效。
         * </p>
         * @defaultValue
         */
        selectedTerrainProviderViewModel?: Cesium.ProviderViewModel;
        /**
         * 确定阴影是否由光源投射
         * <p></p>
         * @defaultValue false
         */
        shadows?: boolean;
        /**
         * 模型动画控制
         * <p></p>
         * @defaultValue
         */
        shouldAnimate?: boolean;
        /**
         * 显示渲染循环错误
         * <p>
         * 如果为true，如果出现渲染循环错误，此小部件将自动向显示包含错误的用户HTML面板。
         * </p>
         * @defaultValue
         */
        showRenderLoopErrors?: boolean;
        /**
         * 选择指示器
         * <p></p>
         * @defaultValue
         */
        selectionIndicator?: boolean;
        /**
         * 天空盒
         * <p>
         * 用来渲染星星的天空盒。当 设置为 undefined 和使用 WGS84 椭球体时，将使用默认的星号。如果设置为 false，没有skyBox，太阳，或月亮将被添加。
         * </p>
         * @defaultValue
         */
        skyBox?: Cesium.SkyBox | false;
        /**
         * 天空大气层
         * <p>
         * 蓝色的天空，以及环绕在地球边缘周围的光芒。在WGS84椭球体使用时启用。设置为 false 来关闭它。
         * </p>
         * @defaultValue
         */
        skyAtmosphere?: Cesium.SkyAtmosphere | false;
        /**
         * 目标帧速率
         * <p>使用默认渲染循环时的目标帧速率。</p>
         * @defaultValue
         */
        targetFrameRate?: number;
        /**
         * 地形
         * <p></p>
         * @defaultValue
         */
        terrain?: Cesium.Terrain;
        /**
         * 地形提供程序
         * <p></p>
         * @defaultValue
         */
        terrainProvider?: Cesium.TerrainProvider;
        /**
         * 地形选择器视图模型
         * <p>
         * 可从基本选择器中选择的供应商模型数组。这个值只有在 `baseLayerPicker` 被设置为true时才有效。
         * </p>
         * @defaultValue
         */
        terrainProviderViewModels?: Cesium.ProviderViewModel[];
        /**
         * 地形阴影 - 确定地形是否从光源投射或接收阴影
         * <p></p>
         * @defaultValue
         */
        terrainShadows?: Cesium.ShadowMode;
        /**
         * 时间线
         * <p></p>
         * @defaultValue
         */
        timeline?: boolean;
        /**
         * 使用浏览器推荐的分辨率进行渲染
         * <p></p>
         * @defaultValue
         */
        useBrowserRecommendedResolution?: boolean;
        /**
         * 使用默认渲染循环
         * <p></p>
         * @defaultValue
         */
        useDefaultRenderLoop?: boolean;
        /**
         * VR 按钮
         * <p></p>
         * @defaultValue
         */
        vrButton?: boolean;
    }

    /**
     * 默认视图选项
     */
    export const defaultViewerOptions: ViewerOptions = {
        animation: false,
        baseLayer: false,
        baseLayerPicker: false,
        fullscreenButton: false,
        geocoder: false,
        homeButton: false,
        // infoBox: true,
        navigationHelpButton: false,
        sceneModePicker: false,         //
        shadows: true,
        shouldAnimate: false,
        // skyBox: false,
        // skyAtmosphere: false,
        timeline: false,
    }


    /**
     * 天空盒
     * @returns see {@link Cesium.SkyBox}
     */
    export function createSkyBox(sources: SkyBoxSources, show: boolean = true): Cesium.SkyBox {
        let sbx: Cesium.SkyBox;
        try {
            sbx = new Cesium.SkyBox({ sources: sources, show: show });
            sbx.show = show
        } catch (error) {
            sbx = Cesium.SkyBox.createEarthSkyBox();
            sbx.show = show
        }
        return sbx;
    }
}

export default Map;
// ----------------------------------------------------------------------------
// {{@@@}}
